﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls;
using Telerik.WinControls.UI;
using FukiERP.Common.Constants;
using FukiERP.Common.DTO;
using FukiERP.Helper;
using FukiERP.Services.DBContext;
using FukiERP.Services.Helper;

namespace FukiERP.Purchase
{
    public partial class frm_Purchasing : Telerik.WinControls.UI.RadForm
    {
        List<FukiERP.Services.DBContext.Product> _products;
        public frm_Purchasing()
        {
            InitializeComponent();
        }

        private void frm_Purchasing_Load(object sender, EventArgs e) {
            FukiERPDataContext context = DataAccess.GetDBContext();
            PresentHelper.LoadProductCate(context, drp_cate);
            LoadSupplier(context);
            // must load before init productCate to prevent firing index change event
            _products = context.Products.ToList();
            LoadPurchaseList(context);
        }

        private void LoadPurchaseList(FukiERPDataContext context) {
            grd_PurchaseOrder.DataSource = context.View_PurchaseOrders.OrderBy(c => c.Date).ThenBy(c => c.Name);
        }
        private void LoadSupplier(FukiERPDataContext context) {
            drp_Supplier.DataSource = context.Suppliers.OrderBy(c => c.Name).ToList();
            drp_Supplier.DisplayMember = ColumName.Col_Name;
            drp_Supplier.SelectedIndex = -1;
            drp_Supplier.Text = CommonConstants.DefaultDropDownValue;
        }

        private void drp_cate_SelectedIndexChanged(object sender, Telerik.WinControls.UI.Data.PositionChangedEventArgs e) {
            if (e.Position != -1 && _products != null && _products.Count() > 0) {
                drp_Product.Items.Clear();
                int cateID = (int) ((RadListDataItem)drp_cate.Items[e.Position].Value).Value;
                List<Services.DBContext.Product> products = _products.Where(c => c.CateID == cateID).OrderBy(c => c.Name).ToList();
                if (products != null && products.Count() > 0) {
                    drp_Product.DataSource = products;
                    drp_Product.DisplayMember = ColumName.Col_Name;
                }
                drp_Product.Text = CommonConstants.DefaultDropDownValue;
            }
        }

        private void tbn_AddProduct_Click(object sender, EventArgs e) {
            errorProvider1.Clear();
            bool isValid = true;
            isValid = isValid && ValidateValue.ValidateDropDown(errorProvider1, drp_Product);
            isValid = isValid && ValidateValue.ValidateNumberGrateThanZeroGroup(errorProvider1, tbx_Quatity, tbx_Cost);
            if (!isValid) {
                MessageBox.Show(MessageConstants.GaneralValidateMessage);
                return;
            }
            ProductPurchase pp = new ProductPurchase();
            pp.ProductID = ((Services.DBContext.Product)drp_Product.SelectedValue).ID;
            pp.ProductName = drp_Product.Text;
            pp.Quantity = Common.Helper.CommonHelper.GetNumber(tbx_Quatity.Text);
            pp.Cost = Common.Helper.CommonHelper.GetNumber(tbx_Cost.Text);
            List<ProductPurchase> purchaseInfo = null;
            if (grd_PurchaseInfo.DataSource == null) {
                purchaseInfo = new List<ProductPurchase>();
            } else {
                purchaseInfo = (List<ProductPurchase>)grd_PurchaseInfo.DataSource;
                grd_PurchaseInfo.DataSource = null;
            }
            ProductPurchase oldPP = purchaseInfo.Where(c => c.ProductID == pp.ProductID).FirstOrDefault();
            if (oldPP != null) {
                oldPP.Quantity = oldPP.Quantity + pp.Quantity;
            } else {
                purchaseInfo.Add(pp);
            }
            grd_PurchaseInfo.DataSource = purchaseInfo;
        }

        private void grd_PurchaseInfo_CellDoubleClick(object sender, GridViewCellEventArgs e) {
            ProductPurchase p = (ProductPurchase)grd_PurchaseInfo.Rows[e.RowIndex].DataBoundItem;
            List<ProductPurchase> purchaseInfo = (List<ProductPurchase>)grd_PurchaseInfo.DataSource;
            grd_PurchaseInfo.DataSource = null;
            purchaseInfo.Remove(p);
            grd_PurchaseInfo.DataSource = purchaseInfo;
        }

        private void tbn_Save_Click(object sender, EventArgs e) {
            if (!PresentHelper.ShowConfirmBox(MessageConstants.CreatePurchaseOrderMessage)) {
                return;
            }
            List<ProductPurchase> purChaseInfo = (List<ProductPurchase>)grd_PurchaseInfo.DataSource;
            if(purChaseInfo == null || purChaseInfo.Count() == 0){
                MessageBox.Show("Thiếu thông tin về sản phẩm");
                return;
            }
            FukiERPDataContext context = DataAccess.GetDBContext();
            PurchaseOrder pOrder = SavePurchaseOrder(context);
            if (pOrder != null) {
                foreach (ProductPurchase po in purChaseInfo) {
                    PurchaseInfo info = new PurchaseInfo();
                    info.PurchaseOrderID = pOrder.ID;
                    info.ProductId = po.ProductID;
                    info.Quantity = po.Quantity;
                    info.CostPrice = po.Cost;
                    // Update Average Cost 
                    UpdateAverageCost( context, info);
                    context.PurchaseInfos.InsertOnSubmit(info);
                }
                context.SubmitChanges();
                CleanForm();
            }
        }

        private void UpdateAverageCost(FukiERPDataContext context, PurchaseInfo info) {
            Services.DBContext.Product product = context.Products.Where(c => c.ID == info.ProductId).FirstOrDefault();
            Inventory inventory = context.Inventories.Where(c => c.ProductID == info.ProductId).FirstOrDefault();
            if (inventory == null) {
                inventory = new Inventory() { ProductID = info.ProductId, Quantity = info.Quantity };
                product.AverageCost = info.CostPrice;
                context.Inventories.InsertOnSubmit(inventory);
            } else { 
                int total = inventory.Quantity + info.Quantity;
                product.AverageCost = (product.AverageCost * inventory.Quantity + info.Quantity * info.CostPrice) / total;
            }
        }

        private PurchaseOrder SavePurchaseOrder(FukiERPDataContext context) {
            PurchaseOrder purOrder = new PurchaseOrder();
            context.PurchaseOrders.InsertOnSubmit(purOrder);
            purOrder.Date = DateTime.Now;
            purOrder.SupplierID = ((FukiERP.Services.DBContext.Supplier)drp_Supplier.SelectedValue).ID;
            purOrder.Reciever = tbx_Reciever.Text;
            purOrder.PurchaseMethod = drp_PurchaseMethod.SelectedItem.Text;
            purOrder.PaymentMethod = _drpPaymentMethod.SelectedItem.Text;
            purOrder.Note = tbx_Note.Text;
            purOrder.PurchaseCode = Guid.NewGuid().ToString();
            context.SubmitChanges();
            return purOrder;
        }

        private void btn_Create_Click(object sender, EventArgs e) {
            CleanForm();
        }

        private void CleanForm() {
            PresentHelper.ClearTextBox(tbx_Cost, tbx_Note, tbx_Quatity, tbx_Reciever);
            PresentHelper.ClearDropBox(drp_cate, drp_Product, drp_PurchaseMethod, drp_Supplier);
            grd_PurchaseInfo.DataSource = null;
            LoadPurchaseList(DataAccess.GetDBContext());
            SetViewPurchaseMode(true);
        }

        private void grd_PurchaseOrder_CellDoubleClick(object sender, GridViewCellEventArgs e) {
            SetViewPurchaseMode(false);
            int currentId = int.Parse(grd_PurchaseOrder.Rows[e.RowIndex].Cells[0].Value.ToString());
            FukiERPDataContext context = DataAccess.GetDBContext();
            List<ProductPurchase> pInfos = context.PurchaseInfos.
                Where(c => c.PurchaseOrderID == currentId).OrderBy(c => c.ProductId).
                Select(c => new ProductPurchase() { ProductID = c.ProductId, Cost = c.CostPrice, Quantity = c.Quantity }).ToList();
            foreach (ProductPurchase pp in pInfos) {
                pp.ProductName = _products.Where(c => c.ID == pp.ProductID).FirstOrDefault().Name;
            }
            grd_PurchaseInfo.DataSource = pInfos;
        }

        private void SetViewPurchaseMode(bool viewMode) {
            tbx_Cost.Enabled = viewMode;
            tbx_Note.Enabled = viewMode;
            tbx_Reciever.Enabled = viewMode;
            tbx_Quatity.Enabled = viewMode;
            tbn_Save.Enabled = viewMode;
            drp_cate.Enabled = viewMode;
            drp_Product.Enabled = viewMode;
            drp_PurchaseMethod.Enabled = viewMode;
            drp_Supplier.Enabled = viewMode;
        }
    }
}
